home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "LeoLib.h"
-
- #define VERSION "1.11"
-
- #if !defined _AMIGA && !defined AMIGA
- typedef short BOOL;
- #endif
- #ifndef TRUE
- #define TRUE 1
- #endif
- #ifndef FALSE
- #define FALSE 0
- #endif
-
- /* The following are for ANSI C compilers with bad stdio.h */
- #if !defined _IOFBF
- #define _IOFBF 0
- #endif
-
- static void SetStupidTerminal(BOOL Stupid);
- static void Bold(FILE *OutFile);
- static void Italics(FILE *OutFile);
- static void Reverse(FILE *OutFile);
- static void Underline(FILE *OutFile);
- static void BoldOff(FILE *OutFile);
- static void ItalicsOff(FILE *OutFile);
- static void ReverseOff(FILE *OutFile);
- static void UnderlineOff(FILE *OutFile);
- static void FGColor(FILE *OutFile, int Color);
- static void BGColor(FILE *OutFile, int Color);
- static void Normal(FILE *OutFile);
- static void StoreTextMode(void);
- static void RestoreTextMode(FILE *OutFile);
-
- static void ReadAGFile(FILE *InFile);
- static void WordAddChar(char NewC);
- static void WordSend(void);
-
- static void SkipSpaces(FILE *InFile);
- static void SkipUntilSpace(FILE *InFile);
- static void SkipToEOL(FILE *InFile);
- static int ReadToUpper(FILE *InFile, char *string, int n);
-
- static void PutInit(FILE *OutFile);
- static void PutWord(char *Str);
- static void PutEOL(void);
- static void PutEnd(void);
- static void PutTab(void);
- static void PutSpace(void);
- static void PutSetWidth(int Width);
- static void PutSetWrap(void);
- static void PutPurgeSpace(void);
-
- static void NodeInit(void);
- static int NodeNumber(char *Str);
- static void NodeEnd(void);
-
- static int AGParseCommand(char *Command, FILE *InFile);
- static int AGArgs(void);
- static char *AGArg(int Arg);
- static char *AGArgU(int Arg);
-
-
- #if defined _AMIGA || defined AMIGA
- static char *Ver = "$VER:GuideCat " VERSION
- #if defined __SASC
- " " __AMIGADATE__ " ©1994-6 Leopold-Soft"
- #endif
- ;
- #endif
-
- static BOOL NodeItalics = TRUE, NodeBold = TRUE, NodeReverse = TRUE,
- LinkItalics = FALSE, LinkBold = FALSE, LinkReverse = TRUE,
- IndexNumbering = TRUE, fileArguments = FALSE, Plain = FALSE,
- Brackets = FALSE;
- static int NodeColor = 1, LinkColor = 1, ColColor = 2;
- static BOOL ColReverse = FALSE;
- static void *InBuff = NULL;
-
-
-
-
- /***********************************\
- * *
- * Main - command line parser *
- * *
- \***********************************/
-
- int main(int argc, char **argv) {
- static int CurrArg = 0;
- static FILE *InFile;
- static char *ColumnsStr;
- static int Columns = 0;
-
- if ((ColumnsStr = getenv("COLUMNS")) && (Columns = atoi(ColumnsStr)))
- PutSetWidth(Columns);
-
- while(++CurrArg < argc) {
- /* NODE OPTIONS */
- if (!strcmp(argv[CurrArg],"-nI")) {
- NodeItalics = TRUE;
- Plain = FALSE;
- } else if (!strcmp(argv[CurrArg],"-ni")) {
- NodeItalics = FALSE;
- Plain = FALSE;
- } else if (!strcmp(argv[CurrArg],"-nB")) {
- NodeBold = TRUE;
- Plain = FALSE;
- } else if (!strcmp(argv[CurrArg],"-nb")) {
- NodeBold = FALSE;
- Plain = FALSE;
- } else if (!strcmp(argv[CurrArg],"-nR")) {
- NodeReverse = TRUE;
- Plain = FALSE;
- } else if (!strcmp(argv[CurrArg],"-nr")) {
- NodeReverse = FALSE;
- Plain = FALSE;
- } else if (!strcmp(argv[CurrArg],"-nC")) {
- if (argc > CurrArg+1) {
- NodeColor = atoi(argv[++CurrArg]);
- if (NodeColor < 1 || NodeColor > 7) {
- NodeColor = 1;
- CurrArg--;
- }
- }
- Plain = FALSE;
- } else if (!strcmp(argv[CurrArg],"-nc")) {
- NodeColor = 1;
- Plain = FALSE;
- /* LINK OPTIONS */
- } else if (!strcmp(argv[CurrArg],"-lI")) {
- LinkItalics = TRUE;
- Plain = FALSE;
- } else if (!strcmp(argv[CurrArg],"-li")) {
- LinkItalics = FALSE;
- Plain = FALSE;
- } else if (!strcmp(argv[CurrArg],"-lB")) {
- LinkBold = TRUE;
- Plain = FALSE;
- } else if (!strcmp(argv[CurrArg],"-lb")) {
- LinkBold = FALSE;
- Plain = FALSE;
- } else if (!strcmp(argv[CurrArg],"-lR")) {
- LinkReverse = TRUE;
- Plain = FALSE;
- } else if (!strcmp(argv[CurrArg],"-lr")) {
- LinkReverse = FALSE;
- Plain = FALSE;
- } else if (!strcmp(argv[CurrArg],"-lC")) {
- if (argc > CurrArg+1) {
- LinkColor = atoi(argv[++CurrArg]);
- if (LinkColor < 1 || LinkColor > 7) {
- LinkColor = 1;
- CurrArg--;
- }
- }
- Plain = FALSE;
- } else if (!strcmp(argv[CurrArg],"-lc")) {
- LinkColor = 1;
- Plain = FALSE;
- /* COLOR OPTIONS */
- } else if (!strcmp(argv[CurrArg],"-cR")) {
- ColReverse = TRUE;
- ColColor = 1;
- Plain = FALSE;
- } else if (!strcmp(argv[CurrArg],"-cr")) {
- ColReverse = FALSE;
- Plain = FALSE;
- } else if (!strcmp(argv[CurrArg],"-cC")) {
- if (argc > CurrArg+1) {
- ColColor = atoi(argv[++CurrArg]);
- if (ColColor < 1 || ColColor > 7) {
- ColColor = 1;
- CurrArg--;
- }
- }
- ColReverse = FALSE;
- Plain = FALSE;
- } else if (!strcmp(argv[CurrArg],"-cc")) {
- ColColor = 1;
- /* OTHER OPTIONS */
- } else if (!strcmp(argv[CurrArg],"-I")) {
- IndexNumbering = TRUE;
- } else if (!strcmp(argv[CurrArg],"-i")) {
- IndexNumbering = FALSE;
- } else if (!strcmp(argv[CurrArg],"-S")) {
- SetStupidTerminal(TRUE);
- } else if (!strcmp(argv[CurrArg],"-s")) {
- SetStupidTerminal(FALSE);
- } else if (!strcmp(argv[CurrArg],"-B")) {
- Brackets = TRUE;
- } else if (!strcmp(argv[CurrArg],"-b")) {
- Brackets = FALSE;
- } else if (!strcmp(argv[CurrArg],"-P")) {
- Plain = TRUE;
- } else if (!strcmp(argv[CurrArg],"-p")) {
- Plain = FALSE;
- } else if (!strcmp(argv[CurrArg],"-A")) {
- Brackets = TRUE;
- } else if (!strcmp(argv[CurrArg],"-a")) {
- Brackets = FALSE;
- } else if (!strcmp(argv[CurrArg],"-w") || !strcmp(argv[CurrArg],"-W")) {
- if (argc > CurrArg+1) {
- static int Tmp;
- Tmp = atoi(argv[++CurrArg]);
- if (Tmp == 0) {
- CurrArg--;
- } else {
- PutSetWidth(Tmp);
- }
- }
- } else if (!strcmp(argv[CurrArg],"-d0")) {
- NodeItalics = TRUE; NodeBold = TRUE; NodeReverse = TRUE;
- LinkItalics = FALSE; LinkBold = FALSE; LinkReverse = TRUE;
- IndexNumbering = TRUE; fileArguments = FALSE; Plain = FALSE;
- Brackets = FALSE; NodeColor = 1; LinkColor = 1;
- ColReverse = FALSE; ColColor = 2;
- SetStupidTerminal(TRUE);
- } else if (!strcmp(argv[CurrArg],"-d1")) {
- NodeItalics = FALSE; NodeBold = TRUE; NodeReverse = FALSE;
- LinkItalics = FALSE; LinkBold = TRUE; LinkReverse = FALSE;
- IndexNumbering = TRUE; fileArguments = FALSE; Plain = FALSE;
- Brackets = FALSE; NodeColor = 3; LinkColor = 3;
- ColReverse = FALSE; ColColor = 2;
- SetStupidTerminal(FALSE);
- } else if (!strcmp(argv[CurrArg],"-d2")) {
- NodeItalics = FALSE; NodeBold = FALSE; NodeReverse = FALSE;
- LinkItalics = FALSE; LinkBold = FALSE; LinkReverse = FALSE;
- IndexNumbering = TRUE; fileArguments = FALSE; Plain = TRUE;
- Brackets = TRUE; NodeColor = 1; LinkColor = 1;
- ColReverse = FALSE; ColColor = 1;
- SetStupidTerminal(TRUE);
- } else if (!strcmp(argv[CurrArg],"-h") || !strcmp(argv[CurrArg],"?")) {
- printf("\nGuideCat " VERSION " ©1994-6 Henrik Herranen\n\n"
- "Usage: %s [?|-h] | [-n[I|i]] | [-n[B|b]] | [-n[R|r]] | [-l[I|i]] | [-l[B|b]] | [-l[R|r]] | [filename]\n\n"
- "-h or ? Show this help page.\n"
- " def: 0 1 2\n"
- "-nI or -ni Turns Italics on/off in node headers on off off\n"
- "-nB or -nb Turns Bold on/off in node headers on off off\n"
- "-nR or -nr Turns Reverse on/off in node headers on off off\n"
- "-nC x or -nc Sets color on/off in node headers off 3 off\n"
- "-lI or -li Turns Italics on/off in links off off off\n"
- "-lB or -lb Turns Bold on/off in links off off off\n"
- "-lR or -lr Turns Reverse on/off in links on off off\n"
- "-lC x or -lc Sets color on/off in links off 3 off\n"
- "-cR or -cr Turns Reverse on/off for colors off off off\n"
- "-cC x or -cc Sets colors on+hilite/off for colors 2 2 off\n"
- "-I or -i Switches node index numbering on/off on on on\n"
- "-S or -s Switches stupid terminal mode on/off on off on\n"
- "-A or -a Brackets around nodes+links on/off off off on\n"
- "-P pr -p plain output on/off off off on\n"
- "-w x (x>=20) Set display width if WORDWRAP used 78 78 78\n"
- "-d0 .. -d2 Use defaults 0..2\n"
- "filename the named file will be read as an AmigaGuide file.\n\n"
- ,argv[0]);
- fileArguments = TRUE;
- } else {
- if (InFile = fopen(argv[CurrArg], "ra")) {
- if (!InBuff) InBuff = malloc(16384);
- if (InBuff) setvbuf(InFile, InBuff, _IOFBF, (size_t) 16384);
- ReadAGFile(InFile);
- fclose(InFile);
- } else {
- fprintf(stderr,"%s: *** ERROR: Couldn't open file '%s'!\n", argv[0], argv[CurrArg]);
- }
- fileArguments = TRUE;
- }
- }
-
- if (!fileArguments) {
- fprintf(stderr,"%s: Reading from standard input. Press "
- #if defined _AMIGA || defined AMIGA
- "ctrl-\\"
- #else
- "ctrl-D"
- #endif
- " to stop if running interactively.\n", argv[0]);
- ReadAGFile(stdin);
- }
-
- return EXIT_SUCCESS;
- }
-
-
-
- /***********************************\
- * *
- * Text formatting functions *
- * *
- \***********************************/
-
- struct TextMode {
- BOOL Bold, Italics, Reverse, Underline;
- int FGColor, BGColor;
- };
-
- static struct TextMode CurrTextMode = {FALSE, FALSE, FALSE, FALSE, 1, 0}, StoredTextMode;
- static BOOL StupidTerminal = TRUE;
-
- static void SetStupidTerminal(BOOL Stupid) {
- StupidTerminal = Stupid;
- }
-
- static void Bold(FILE *OutFile) {
- if (!CurrTextMode.Bold) {
- fprintf(OutFile,"\033[1m");
- CurrTextMode.Bold = TRUE;
- }
- }
-
- static void Italics(FILE *OutFile) {
- if (!CurrTextMode.Italics) {
- fprintf(OutFile,"\033[3m");
- CurrTextMode.Italics = TRUE;
- }
- }
-
- static void Reverse(FILE *OutFile) {
- if (!CurrTextMode.Reverse) {
- fprintf(OutFile,"\033[7m");
- CurrTextMode.Reverse = TRUE;
- }
- }
-
- static void Underline(FILE *OutFile) {
- if (!CurrTextMode.Underline) {
- fprintf(OutFile,"\033[4m");
- CurrTextMode.Underline = TRUE;
- }
- }
-
- /* The following function is only for internal use */
- /* -> no prototype provided */
- static void SetTextModeOnStupidTerminal(FILE *OutFile) {
- struct TextMode TmpTextMode = CurrTextMode;
- Normal(OutFile);
- if (TmpTextMode.Bold) Bold(OutFile);
- if (TmpTextMode.Italics) Italics(OutFile);
- if (TmpTextMode.Reverse) Reverse(OutFile);
- if (TmpTextMode.Underline) Underline(OutFile);
- if (TmpTextMode.FGColor != 1) FGColor(OutFile, StoredTextMode.FGColor);
- if (TmpTextMode.BGColor != 0) BGColor(OutFile, StoredTextMode.BGColor);
- }
-
- static void BoldOff(FILE *OutFile) {
- if (CurrTextMode.Bold) {
- CurrTextMode.Bold = FALSE;
- if (StupidTerminal) SetTextModeOnStupidTerminal(OutFile);
- else fprintf(OutFile,"\033[22m");
- }
- }
-
- static void ItalicsOff(FILE *OutFile) {
- if (CurrTextMode.Italics) {
- CurrTextMode.Italics = FALSE;
- if (StupidTerminal) SetTextModeOnStupidTerminal(OutFile);
- else fprintf(OutFile,"\033[23m");
- }
- }
-
- static void ReverseOff(FILE *OutFile) {
- if (CurrTextMode.Reverse) {
- CurrTextMode.Reverse = FALSE;
- if (StupidTerminal) SetTextModeOnStupidTerminal(OutFile);
- else fprintf(OutFile,"\033[27m");
- }
- }
-
- static void UnderlineOff(FILE *OutFile) {
- if (CurrTextMode.Underline) {
- CurrTextMode.Underline = FALSE;
- if (StupidTerminal) SetTextModeOnStupidTerminal(OutFile);
- else fprintf(OutFile,"\033[24m");
- }
- }
-
- static void FGColor(FILE *OutFile, int Color) {
- fprintf(OutFile,"\033[3%dm", Color & 7);
- CurrTextMode.FGColor = Color & 7;
- }
-
- static void BGColor(FILE *OutFile, int Color) {
- fprintf(OutFile,"\033[4%dm", Color & 7);
- CurrTextMode.BGColor = Color & 7;
- }
-
- static void Normal(FILE *OutFile) {
- CurrTextMode.Bold = FALSE;
- CurrTextMode.Italics = FALSE;
- CurrTextMode.Reverse = FALSE;
- CurrTextMode.Underline = FALSE;
- CurrTextMode.FGColor = 1;
- CurrTextMode.BGColor = 0;
- fprintf(OutFile,"\033[0m");
- }
-
- static void StoreTextMode(void) {
- StoredTextMode = CurrTextMode;
- }
-
- static void RestoreTextMode(FILE *OutFile) {
- if (CurrTextMode.Bold != StoredTextMode.Bold ||
- CurrTextMode.Italics != StoredTextMode.Italics ||
- CurrTextMode.Reverse != StoredTextMode.Reverse ||
- CurrTextMode.Underline != StoredTextMode.Underline ||
- CurrTextMode.FGColor != StoredTextMode.FGColor ||
- CurrTextMode.BGColor != StoredTextMode.BGColor) {
- if (CurrTextMode.Bold || CurrTextMode.Italics ||
- CurrTextMode.Reverse || CurrTextMode.Underline ||
- CurrTextMode.FGColor != 1 || CurrTextMode.BGColor != 0) {
- Normal(OutFile);
- if (StoredTextMode.Bold) Bold(OutFile);
- if (StoredTextMode.Italics) Italics(OutFile);
- if (StoredTextMode.Reverse) Reverse(OutFile);
- if (StoredTextMode.Underline) Underline(OutFile);
- if (StoredTextMode.FGColor != 1) FGColor(OutFile, StoredTextMode.FGColor);
- if (StoredTextMode.BGColor != 0) BGColor(OutFile, StoredTextMode.BGColor);
- }
- }
- }
-
-
-
-
- static int ReadToUpper(FILE *InFile, char *string, int n) {
- static int i, InC;
-
- for (i=0; i<n; i++) {
- if ((InC = fgetc(InFile)) != -1) {
- *(string++) = ToUpper(InC);
- } else {
- return i;
- }
- }
- return n;
- }
-
- static void SkipSpaces(FILE *InFile) {
- static int InC;
- while (IsSpace(InC = fgetc(InFile)));
- if (InC != -1) ungetc(InC, InFile);
- }
-
- static void SkipUntilSpace(FILE *InFile) {
- static int InC;
- while (!IsSpace(InC = fgetc(InFile)) && InC != -1);
- if (InC != -1) ungetc(InC, InFile);
- }
-
- static void SkipToEOL(FILE *InFile) {
- static int InC;
- while ((InC = fgetc(InFile)) != -1 && InC != '\n');
- if (InC != -1) ungetc(InC, InFile);
- }
-
-
-
-
- /***********************************\
- * *
- * The AmigaGuide parser *
- * *
- \***********************************/
-
- static void ReadAGFile(FILE *InFile) {
- static char TmpStr[81], TmpStr2[81];
- static int InC, i;
- BOOL LastNewLine = TRUE, InsideNode = FALSE, Command = FALSE;
-
- ReadToUpper(InFile,TmpStr,10);
- if (memcmp(TmpStr,"@DATABASE ",10)) {
- fprintf(stderr," *** ERROR: Not a valid AmigaGuide file!\n");
- return;
- }
-
- printf("\nDATABASE: ");
- while ((InC = fgetc(InFile)) != '\n') {
- if (InC == -1) {
- fprintf(stderr," *** ERROR: Unexpected end of file!\n");
- return;
- } else {
- fputc(InC, stdout);
- }
- }
- fputc('\n', stdout);
-
- PutInit(stdout);
- NodeInit();
-
- while (!feof(InFile)) {
- InC = fgetc(InFile);
- if (InC == '@') { /* The command character @ */
- InC = fgetc(InFile);
- if (LastNewLine && InC != '{') { /* If a command line */
- ungetc(InC, InFile);
- AGParseCommand(NULL, InFile);
- if (feof(InFile)) return;
- if (!strcmp(AGArgU(0), "NODE")) { /* recognize commands */
- if (!InsideNode) {
- InsideNode = TRUE;
- Normal(stdout);
- printf("\n\n\n%sNODE: ", (Brackets ? "[" : ""));
- if (!Plain) {
- if (NodeItalics) Italics(stdout);
- if (NodeBold) Bold(stdout);
- if (NodeReverse) Reverse(stdout);
- if (NodeColor != 1) FGColor(stdout, NodeColor);
- }
- if (IndexNumbering) printf("(%d) ", NodeNumber(AGArgU(1)));
- if (AGArgs() > 2) {
- printf("%s", AGArg(2));
- } else {
- printf("*** Internal name: %s ***", AGArgU(1));
- }
- if ((NodeItalics || NodeBold || NodeReverse || NodeColor != 1)
- && !Plain) Normal(stdout);
- printf("%s\n", (Brackets ? "]" : ""));
- }
- } else if (!strcmp(AGArgU(0), "ENDNODE")) {
- if (InsideNode) {
- InsideNode = FALSE;
- }
- } else if (!strcmp(AGArgU(0), "WORDWRAP")) {
- PutSetWrap();
- } /* End of recognized commands */
- InC = '\n';
- Command = TRUE;
- } else if (InC == '{') { /* If link or inline command */
- ungetc(InC, InFile);
- AGParseCommand(NULL, InFile);
- if (AGArgs() >= 3 && !strcmp(AGArgU(1), "LINK")) { /* If link */
- WordSend();
- if (!Plain) {
- StoreTextMode();
- Normal(stdout);
- if (LinkItalics) Italics(stdout);
- if (LinkBold) Bold(stdout);
- if (LinkReverse) Reverse(stdout);
- if (LinkColor != 1) FGColor(stdout, LinkColor);
- }
- strncpy(TmpStr, AGArg(0), 60);
- if (IndexNumbering) {
- sprintf(TmpStr2, "(%d) %s", NodeNumber(AGArgU(2)), TmpStr);
- strcpy(TmpStr, TmpStr2);
- }
- if (Brackets) {
- sprintf(TmpStr2, "[%s]", TmpStr);
- strcpy(TmpStr, TmpStr2);
- }
- PutWord(TmpStr);
- if (!Plain) RestoreTextMode(stdout);
- InC = '}';
- Command = TRUE;
- } else { /* else: Inline command */
- i = 0;
- if (!Plain) {
- if (!strcmp(AGArgU(0), "B")) {
- WordSend();
- Bold(stdout);
- } else if (!strcmp(AGArgU(0), "UB")) {
- WordSend();
- BoldOff(stdout);
- } else if (!strcmp(AGArgU(0), "I")) {
- WordSend();
- Italics(stdout);
- } else if (!strcmp(AGArgU(0), "UI")) {
- WordSend();
- ItalicsOff(stdout);
- } else if (!strcmp(AGArgU(0), "U")) {
- WordSend();
- Underline(stdout);
- } else if (!strcmp(AGArgU(0), "UU")) {
- WordSend();
- UnderlineOff(stdout);
- } else if (!strcmp(AGArgU(0), "FG")) {
- static int Tmp;
- WordSend();
- if (!strcmp(AGArgU(1), "TEXT")) {
- Tmp = 1;
- } else if (!strcmp(AGArgU(1), "HIGHLIGHT")) {
- Tmp = ColColor;
- } else if (!strcmp(AGArgU(1), "BACKGROUND")) {
- Tmp = 0;
- } else {
- Tmp = 1;
- }
- if (ColColor != 1) FGColor(stdout, Tmp);
- else if (Tmp != 1 && ColReverse) Reverse(stdout);
- else ReverseOff(stdout);
- } else if (!strcmp(AGArgU(0), "BG")) {
- static int Tmp;
- WordSend();
- if (!strcmp(AGArgU(1), "TEXT")) {
- Tmp = 1;
- } else if (!strcmp(AGArgU(1), "HIGHLIGHT")) {
- Tmp = ColColor;
- } else if (!strcmp(AGArgU(1), "BACKGROUND")) {
- Tmp = 0;
- } else {
- Tmp = 0;
- }
- if (ColColor != 1) BGColor(stdout, Tmp);
- else if (Tmp != 0 && ColReverse) Reverse(stdout);
- else ReverseOff(stdout);
- }
- }
- Command = TRUE;
- }
- } else { /* There was an @ but no command, so @ must be displayed */
- ungetc(InC, InFile);
- InC = '@';
- }
- }
-
- if (!Command && InC != -1 && InsideNode) { /* If no command */
- if (InC == '\\') InC = fgetc(InFile); /* '\' is the escape character */
- if (InC == '\n' || InC == '\t' || InC == ' ') {
- WordSend();
- if (InC == '\n') PutEOL();
- else if (InC == '\t') PutTab();
- else PutSpace();
- } else {
- WordAddChar(InC);
- }
- }
-
- LastNewLine = (InC == '\n');
- Command = FALSE;
- }
-
- PutEnd();
- NodeEnd();
- if (!Plain) Normal(stdout);
- }
-
-
-
- #define MAX_WORD_LENGTH 80
-
- static char Word[MAX_WORD_LENGTH+1];
- static int WordLen = 0;
-
- static void WordAddChar(char NewC) {
- if (WordLen >= MAX_WORD_LENGTH) WordSend();
- Word[WordLen++] = NewC;
- }
-
- static void WordSend(void) {
- Word[WordLen] = '\000';
- PutWord(Word);
- WordLen = 0;
- }
-
-
-
- /***********************************\
- * *
- * Text displaying put-routines *
- * *
- \***********************************/
-
- static FILE *PutFile=NULL;
- static int PutPos, PutMaxColumn = 77;
- static BOOL PutWrap;
- static BOOL PutLastSpace;
-
- static void PutInit(FILE *OutFile) {
- PutFile = OutFile;
- PutPos = 0;
- PutWrap = FALSE;
- PutLastSpace = FALSE;
- }
-
- static void PutWord(char *Str) {
- static int Len;
-
- if (PutFile) {
- /* printf("PW: Len=%d, Str=%s\n", strlen(Str), Str);*/
- Len = strlen(Str);
- if (PutWrap) {
- if (PutPos + Len >= PutMaxColumn) {
- fprintf(PutFile, "\n%s", Str);
- PutPos = Len - 1;
- } else {
- if (PutLastSpace) {
- fputc(' ', PutFile);
- PutPos++;
- }
- fprintf(PutFile, "%s", Str);
- PutPos += Len;
- }
- } else {
- PutPos += Len;
- if (PutLastSpace) {
- fputc(' ', PutFile);
- PutPos++;
- }
- fprintf(PutFile, "%s", Str);
- }
- PutLastSpace = FALSE;
- }
- }
-
- static void PutEOL(void) {
- if (PutFile) {
- fputc('\n', PutFile);
- PutPos = 0;
- PutLastSpace = FALSE;
- }
- }
-
- static void PutTab(void) {
- if (PutFile) {
- PutPurgeSpace();
- fputc('\t', PutFile);
- PutPos = (PutPos + 8) & (~7);
- }
- }
-
- static void PutSpace(void) {
- if (PutFile) {
- if (PutWrap) {
- if (PutLastSpace) {
- PutLastSpace = FALSE;
- PutWord(" ");
- }
- PutLastSpace = TRUE;
- } else {
- PutWord(" ");
- }
- }
- }
-
- static void PutPurgeSpace(void) {
- if (PutFile) {
- if (PutLastSpace) {
- if (PutPos + 1 >= PutMaxColumn) {
- fputc('\n', PutFile);
- PutPos = 0;
- } else {
- fputc(' ', PutFile);
- PutPos++;
- }
- }
- PutLastSpace = FALSE;
- }
- }
-
- static void PutSetWidth(int Width) {
- if (Width < 20) Width = 20;
-
- PutMaxColumn = Width - 1;
- }
-
- static void PutSetWrap(void) {
- PutWrap = TRUE;
- }
-
- static void PutEnd(void) {
- PutFile = NULL;
- }
-
-
- struct NodeNode {
- struct NodeNode *Left;
- struct NodeNode *Right;
- long Index;
- char *Text;
- };
-
-
-
-
- /***********************************\
- * *
- * Node handling routines *
- * *
- \***********************************/
-
- static int NodeAmount = -1;
- static struct NodeNode *NodeNode=NULL;
-
-
- /* The following function is only for internal use */
- /* -> no prototype provided */
- static struct NodeNode *AddNode(char *Str) {
- static struct NodeNode *NewNode;
-
- NewNode = malloc(sizeof(struct NodeNode) + strlen(Str) + 1);
- if (NewNode) {
- NewNode -> Left = NULL;
- NewNode -> Right = NULL;
- NewNode -> Index = ++NodeAmount;
- NewNode -> Text = ((char *) NewNode) + sizeof(struct NodeNode);
- strcpy(NewNode -> Text, Str);
- } else {
- fprintf(stderr," *** PANIC: Couldn't allocate memory!\n");
- exit(EXIT_FAILURE);
- }
-
- return NewNode;
- }
-
-
-
- /* The following function is only for internal use */
- /* -> no prototype provided */
- static int FindNode(struct NodeNode *CurrNode, char *Str) {
- int Tmp;
-
- if (CurrNode == NULL) {
- NodeNode = AddNode(Str);
- return 1;
- } else {
- Tmp = strcmp(Str, CurrNode->Text);
- if (Tmp < 0) {
- if (CurrNode->Left) {
- return FindNode(CurrNode->Left, Str);
- } else {
- CurrNode -> Left = AddNode(Str);
- return CurrNode -> Left -> Index;
- }
- } else if (Tmp>0) {
- if (CurrNode->Right) {
- return FindNode(CurrNode->Right, Str);
- } else {
- CurrNode -> Right = AddNode(Str);
- return CurrNode -> Right -> Index;
- }
- } else {
- return CurrNode -> Index;
- }
- }
- }
-
-
-
-
- static int NodeNumber(char *Str) {
- if (NodeAmount >= 0) return FindNode(NodeNode, Str);
-
- return -1;
- }
-
-
-
-
- static void NodeInit(void) {
- NodeEnd();
- NodeAmount = 0;
- }
-
-
-
- /* The following function is only for internal use */
- /* -> no prototype provided */
- static void FreeNodes(struct NodeNode *CurrNode) {
- if (CurrNode -> Left) FreeNodes(CurrNode->Left);
- if (CurrNode -> Right) FreeNodes(CurrNode->Right);
- free(CurrNode);
- }
-
-
-
- static void NodeEnd(void) {
- if (NodeNode && NodeAmount >= 0) FreeNodes(NodeNode);
- NodeNode = NULL;
- NodeAmount = -1;
- }
-
-
-
-
- /***********************************\
- * *
- * AmigaGuide parsing routines *
- * *
- \***********************************/
-
- #define AG_MAX_CHARS_PER_ARGUMENT 80
- #define AG_MAX_ARGUMENTS_PER_COMMAND 4
-
- static char AGOriginalArgument[AG_MAX_ARGUMENTS_PER_COMMAND][AG_MAX_CHARS_PER_ARGUMENT+1];
- static char AGUppercaseArgument[AG_MAX_ARGUMENTS_PER_COMMAND][AG_MAX_CHARS_PER_ARGUMENT+1];
- static int AGArguments;
- static char AGNULL = '\000';
-
- /*-----------------------------------------------------------------*\
- | |
- | AGParseCommand - read AmigaGuide command from a string or file |
- | and parse it. |
- | |
- | Synopsis: |
- | int Args = AGParseCommand(char *Command, NULL); |
- | int Args = AGParseCommand(NULL, FILE *InFile); |
- | |
- | Function: |
- | Reads an AmigaGuide command either from a string or a file and |
- | parses it. AGParseCommand assumes that leading @ is not in the |
- | string / has been read from the file. If the first character is |
- | "{" the command is assumed to be an inline command, otherwise |
- | it is assumed to be a full command line. |
- | |
- | Inputs: |
- | char *Command - if not NULL, this is taken to be the Command |
- | FILE *InFile - if not NULL, this is the file where the Command |
- | will be read. |
- | Command and InFile are mutually exclusive. |
- | |
- | Result: |
- | Args - The amount of arguments read from the command |
- | |
- \*-----------------------------------------------------------------*/
-
- static int AGParseCommand(char *Command, FILE *InFile) {
- int CPos = -1, ArgPos = 0;
- BOOL InQuotes = FALSE, GoQuotes = FALSE, CommandLine = FALSE, Quit = FALSE;
- static int Curr;
-
- AGArguments = 0;
-
- Curr = fgetc(InFile);
- if (Curr != '{') {
- CommandLine = TRUE;
- ungetc(Curr, InFile);
- }
-
- do {
- if (!InFile) Curr = (unsigned char) Command[++CPos];
- else Curr = fgetc(InFile);
-
- if (!Curr || Curr == -1 || Curr == '\n' ||
- !CommandLine && !InQuotes && Curr == '}') {
- Curr = ' ';
- Quit = TRUE;
- }
-
- if (Curr == '"') {
- Curr = ' ';
- if (!InQuotes) GoQuotes = TRUE;
- else InQuotes = FALSE;
- }
-
- if(IsSpace(Curr) && ArgPos && !InQuotes) {
- if (AGArguments <= AG_MAX_ARGUMENTS_PER_COMMAND) {
- AGOriginalArgument[AGArguments-1][ArgPos] = '\000';
- AGUppercaseArgument[AGArguments-1][ArgPos] = '\000';
- }
- ArgPos = 0;
- } else {
- if (ArgPos < AG_MAX_CHARS_PER_ARGUMENT && (!IsSpace(Curr) || InQuotes)) {
- if (!ArgPos) AGArguments++;
- if (AGArguments <= AG_MAX_ARGUMENTS_PER_COMMAND) {
- AGOriginalArgument[AGArguments-1][ArgPos] = Curr;
- AGUppercaseArgument[AGArguments-1][ArgPos] = ToUpper(Curr);
- }
- ArgPos++;
- }
- }
-
- if (GoQuotes) {
- InQuotes = TRUE;
- GoQuotes = FALSE;
- }
- } while (!Quit);
-
- if (AGArguments > AG_MAX_ARGUMENTS_PER_COMMAND)
- AGArguments = AG_MAX_ARGUMENTS_PER_COMMAND;
-
- return AGArguments;
- }
-
-
- /*-----------------------------------------------------------------*\
- | |
- | AGArgs - returns last AmigaGuide command argument count |
- | |
- | Synopsis: |
- | int Args = AGArgs(); |
- | |
- | Function: |
- | Returns argument count from last call of AGParseCommand() |
- | |
- | Inputs: |
- | |
- | Result: |
- | Args - The amount of arguments read from the command |
- | |
- \*-----------------------------------------------------------------*/
-
- static int AGArgs(void) {
- return AGArguments;
- }
-
-
- /*-----------------------------------------------------------------*\
- | |
- | AGArg - returns desired argument from last AmigaGuide command |
- | |
- | Synopsis: |
- | char *Arg = AGArg(int ArgNo); |
- | |
- | Function: |
- | Returns desired argument from last call of AGParseCommand(). |
- | |
- | Inputs: |
- | ArgNo - 0 .. AGArgs()-1 |
- | |
- | Result: |
- | Arg - A pointer to the desired argument. If ArgNo was out of |
- | range, a pointer to an empty string is returned. |
- | |
- \*-----------------------------------------------------------------*/
-
- static char *AGArg(int Arg) {
- if (Arg <= AG_MAX_ARGUMENTS_PER_COMMAND && Arg >= 0) return AGOriginalArgument[Arg];
- else return &AGNULL;
- }
-
- /*-----------------------------------------------------------------*\
- | |
- | AGArg - returns desired argument from last AmigaGuide command |
- | converted to uppercase. |
- | |
- | Synopsis: |
- | char *Arg = AGArg(int ArgNo); |
- | |
- | Function: |
- | Returns desired argument from last call of AGParseCommand() |
- | converted to uppercase letters. |
- | |
- | Inputs: |
- | ArgNo - 0 .. AGArgs()-1 |
- | |
- | Result: |
- | Arg - A pointer to the desired argument. If ArgNo was out of |
- | range, a pointer to an empty string is returned. |
- | |
- \*-----------------------------------------------------------------*/
-
- static char *AGArgU(int Arg) {
- if (Arg <= AG_MAX_ARGUMENTS_PER_COMMAND && Arg >= 0) return AGUppercaseArgument[Arg];
- else return &AGNULL;
- }
-